<?php

namespace App\Admin\Eloquent;

use App\Exceptions\BusinessException;

class Code extends Model
{	
	/**
	 * 设置逐渐 id
	 *
	 * @var string
	 */
	protected $primaryKey = 'code';

	/**
     * 设置主键 id 不自增
     *
     * @var bool
     */
    public $incrementing = false;

	/**
     * 实例化模型时, 可批量赋值属性白名单
     *
     * @var array
     */
    protected $fillable = [
        'code', 'type_id','name', 'parent_code', 'description', 'sort', 'tree'
    ];

    /**
	 * 按 id 超着代码类别
	 *
	 * @param  mixed $typeId
	 * @return App\CodeType
	 */
	protected static function findCodeTypeById($typeId)
	{
		return CodeType::findFromCachedCodeTypes($typeId);
	}

	/**
	 * 通过 type_id 查询代码
	 * 
	 * @param  mixed $typeId 代码类别 id
	 * @return \App\Admin\Eloquent\Code[]
	 */
	public static function getByTypeId($typeId)
	{
		return static::findCodeTypeById($typeId)->cachedCodes();
	}

	/**
	 * 通过 code 和 type_id 查找代码
	 * 
	 * @param  mixed $code
	 * @param  mixed $typeId
	 * @return \App\Admin\Eloquent\Code
	 */
	public static function findByCodeAndTypeId($codeId, $typeId)
	{
		foreach (static::getByTypeId($typeId) as $code) {
	        if ($code->code == $codeId) {
	            return $code;
	        }
	    }

	    return null;
	}

	/**
	 * 保存代码
	 * 
	 * @param  array  $options
	 *
	 * @throws \App\Exceptions\BusinessException
	 */
	public function save(array $options = [])
	{
		if ( !empty($this->parent_code) ) {
			if ($parent = $this->parent()) {
				$this->level = $parent->level + 1;
			} else {
				throw new BusinessException('找不到父代码->'.$this->parent_code);
			}
		} else {
			$this->parent_code = null;
		}

		// 清空缓存代码
    	$this->codeType()->clearCachedCodes();

		return parent::save($options);
	}

	/**
	 * 删除代码类
	 *
	 * @return bool|null
	 */
	public function delete()
	{
		if ($this->hasChildren()) {
	 		throw new BusinessException('代码 '.$this->code.' 下不能有子代码');
		}

		$deleted = parent::delete();

		// 清空缓存代码
    	$this->codeType()->clearCachedCodes();

		return $deleted;
	}

	/**
	 * 代码类别
	 *
	 * @return App\Admin\Eloquent\CodeType
	 */
	public function codeType()
	{
		return static::findCodeTypeById($this->type_id);
	}

	/**
	 * 父代码
	 * 
	 * @return App\Admin\Eloquent\Code
	 */
	public function parent()
	{
		return static::find($this->parent_code);
	}

	/**
	* 是否有子代码
	*
	* @return bool
	*/
	public function hasChildren()
	{
		if (static::where('parent_code', $this->code)->exists()) {
	 		return true;
		}

		return false;
	}
}